package com.lwbldy.modules.student.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.lwbldy.common.shiro.ShiroUtils;
import com.lwbldy.common.tools.HttpRequest;
import com.lwbldy.common.tools.R;
import com.lwbldy.common.tools.SignUtil;
import com.lwbldy.modules.student.domain.*;
import com.lwbldy.modules.student.mapper.*;
import com.lwbldy.modules.student.service.IPreRegistrationService;

import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service("preRegistrationService")
public class PreRegistrationServiceImpl implements IPreRegistrationService {



    @Resource
    PreRegistrationMapper preRegistrationMapper;
    @Resource
    PreLogMapper preLogMapper;

    @Resource
    SchoolDao schoolDao;
    @Resource
    MajorDao majorDao;
    @Resource
    ChargesItemsDao chargesItemsDao;


    @Value("${appid}")
    String appid;

    @Value("${sch_code}")
    String sch_code;
    @Value("${bsurl}")
    String baseURL;

    @Override
    public List<PreRegistration> selectList(PreRegistration param) {
        return preRegistrationMapper.selectList(param);
    }

    @Override
    public PageInfo<PreRegistration> page(PreRegistration param) {
        List<PreRegistration> preRegistrations = preRegistrationMapper.selectList(param);
        return new PageInfo<>(preRegistrations);
    }

    @Override
    public Integer insert(PreRegistration preRegistration) {
        return preRegistrationMapper.insert(preRegistration);
    }

    @Override
    public PreRegistration selectById(Integer id) {
        return preRegistrationMapper.selectById(id);
    }

    @Override
    public Integer updateById(PreRegistration preRegistration) {
        return preRegistrationMapper.updateById(preRegistration);
    }

    @Override
    public Integer deleteById(Integer id) {
        return preRegistrationMapper.deleteById(id);
    }

    @Override
    public Integer deleteByIds(Object[] ids) {
        return preRegistrationMapper.deleteByIds(ids);
    }

    @Override
    public R putStudent(int id) {
        PreRegistration preRegistration = preRegistrationMapper.selectById(id);
        return putStudent(preRegistration);
    }

    private R putStudent(PreRegistration preRegistration){
        JSONArray stuList = new JSONArray();
        JSONObject stuMsg = new JSONObject();
        stuMsg.put("stu_name", preRegistration.getName());
        stuMsg.put("stu_idcard", preRegistration.getIdCard());
        stuMsg.put("stu_number", preRegistration.getId()+"");

//        stuMsg.put("enter_year", "2013");
//        stuMsg.put("year_system", "4");
//        stuMsg.put("birthday", "1999-08-09");
//        stuMsg.put("stu_status", "1");
//        stuMsg.put("stu_address", "安徽省合肥市高新区");
//        stuMsg.put("stu_gender", "1");
//        stuMsg.put("bank_name", "中国银行");
//        stuMsg.put("bank_no", "622233552233669");
//        stuMsg.put("phone_number", "13888996655");
//        stuMsg.put("stu_email", "123456789@qq.com");
//        stuMsg.put("remark", "测试学生");
        stuList.add(stuMsg);

        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", appid);
        jsonParam.put("sch_code", sch_code);
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233");
        jsonParam.put("stu_list", stuList);
        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, SignUtil.privateKey);
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData);
        String url = baseURL+"edupay/api/pay/putstudents";
        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        System.out.println("result:"+resultStr);
        JSONObject resultObj = JSONObject.parseObject(resultStr);
        if(resultObj.getInteger("code") == 0){
            return R.ok();
        }else{
            return R.error("推送失败");
        }
    }

    private R putStudent2(PreRegistration preRegistration,School school){
        JSONArray stuList = new JSONArray();
        JSONObject stuMsg = new JSONObject();
        stuMsg.put("stu_name", preRegistration.getName());
        stuMsg.put("stu_idcard", preRegistration.getIdCard());
        stuMsg.put("stu_number", preRegistration.getId()+"");
        stuMsg.put("remark", preRegistration.getLevelName()+"-"+preRegistration.getMajorName());

//        stuMsg.put("enter_year", "2013");
//        stuMsg.put("year_system", "4");
//        stuMsg.put("birthday", "1999-08-09");
//        stuMsg.put("stu_status", "1");
//        stuMsg.put("stu_address", "安徽省合肥市高新区");
//        stuMsg.put("stu_gender", "1");
//        stuMsg.put("bank_name", "中国银行");
//        stuMsg.put("bank_no", "622233552233669");
//        stuMsg.put("phone_number", "13888996655");
//        stuMsg.put("stu_email", "123456789@qq.com");
//        stuMsg.put("remark", "测试学生");
        stuList.add(stuMsg);

        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", school.getAppid());
        jsonParam.put("sch_code", school.getSchCode());
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233");
        jsonParam.put("stu_list", stuList);
        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, school.getPrivateKey());
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData);
        String url = baseURL+"edupay/api/pay/putstudents";
        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        System.out.println("result:"+resultStr);
        JSONObject resultObj = JSONObject.parseObject(resultStr);
        if(resultObj.getInteger("code") == 0){
            return R.ok();
        }else{
            return R.error("推送失败");
        }
    }


    @Override
    public R putStudentList(Object[] ids) {
        List<PreRegistration> list = preRegistrationMapper.selectByIds(ids);
        JSONArray stuList = new JSONArray();
//
        for(PreRegistration preRegistration : list){
            JSONObject stuMsg = new JSONObject();
            stuMsg.put("stu_name", preRegistration.getName());
            stuMsg.put("stu_idcard", preRegistration.getIdCard());
            stuMsg.put("stu_number", preRegistration.getId());
            stuList.add(stuMsg);
        }


//        stuMsg.put("enter_year", "2013");
//        stuMsg.put("year_system", "4");
//        stuMsg.put("birthday", "1999-08-09");
//        stuMsg.put("stu_status", "1");
//        stuMsg.put("stu_address", "安徽省合肥市高新区");
//        stuMsg.put("stu_gender", "1");
//        stuMsg.put("bank_name", "中国银行");
//        stuMsg.put("bank_no", "622233552233669");
//        stuMsg.put("phone_number", "13888996655");
//        stuMsg.put("stu_email", "123456789@qq.com");
//        stuMsg.put("remark", "测试学生");


        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", appid);
        jsonParam.put("sch_code", sch_code);
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233");
        jsonParam.put("stu_list", stuList);
        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, SignUtil.privateKey);
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData);
        String url = baseURL+"edupay/api/pay/putstudents";
        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        System.out.println("result:"+resultStr);
        JSONObject resultObj = JSONObject.parseObject(resultStr);
        if(resultObj.getInteger("code") == 0){
            return R.ok();
        }else{
            return R.error("推送失败");
        }
    }

    @Override
    public synchronized R billStudent(int id, Map<String,Object> paramMap,double moneyAll) {
        PreRegistration preRegistration = preRegistrationMapper.selectById(id);
        // 先推学生
        putStudent(preRegistration);

        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", appid);
        jsonParam.put("sch_code", sch_code);
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233"); // 随机字符串

        jsonParam.put("bill_no",uuid);
        jsonParam.put("total_amount",moneyAll);

        // 学生信息
        JSONObject stuMsg = new JSONObject();
        stuMsg.put("stu_name", preRegistration.getName());
        stuMsg.put("stu_idcard", preRegistration.getIdCard());
        stuMsg.put("stu_number", preRegistration.getId()+"");
        jsonParam.put("stu_info",stuMsg);

        JSONArray chargeList = new JSONArray();
        for(String key : paramMap.keySet()){

            JSONObject chargeItems1 = new JSONObject();
            chargeItems1.put("item_code",key);
            chargeItems1.put("item_amount",paramMap.get(key));
            chargeList.add(chargeItems1);
        }
        jsonParam.put("charge_items",chargeList);
        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, SignUtil.privateKey);
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData); //签名
        String url = baseURL+"edupay/api/pay/putbill";

        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        JSONObject resultObj = JSONObject.parseObject(resultStr);
        PreLog preLog = new PreLog();
        preLog.setCreateTime(new Date());
        preLog.setBillMoney(moneyAll);
        preLog.setStatus(resultObj.getInteger("code"));
        preLog.setBillNo(uuid);
        preLog.setSendJson(jsonStr);
        preLog.setStuIdcard(preRegistration.getIdCard());
        preLog.setStuName(preRegistration.getName());
        preLog.setSchoolId(1);
        preLog.setRegistrationId(preRegistration.getId());
        preLogMapper.insert(preLog);

        preRegistration.setStatus(1); //推送成功

        preRegistrationMapper.updateStatus(preRegistration);

        if(resultObj.getInteger("code") == 0){
            return R.ok();
        }else{
            return R.error("推送失败");
        }

    }




    @Override
    public synchronized R billStudent(int id) {

        PreRegistration preRegistration = preRegistrationMapper.selectById(id);
        if(preRegistration == null){
            return R.error("没有找到该学生");
        }

        if(preRegistration.getStatus() == null || preRegistration.getStatus() != 0){
            return R.error("已经提交过缴费了，请勿重新提交");
        }

        School school = schoolDao.queryObject(preRegistration.getSchoolId());
        if(school == null){
            return R.error("没有关联学校的异常数据");
        }

        // 判断是否已经招满
        Major major = majorDao.queryObject(preRegistration.getMajorId());
        if(major.getPlanNumber() <= major.getTsrs()){
            return R.error("该专业已经招满，不能推送学生。");
        }

        // 先推学生
        putStudent2(preRegistration,school);
        List<ChargesItems> chargesItemsList = chargesItemsDao.queryByMajorId(preRegistration.getMajorId());
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", school.getAppid());
        jsonParam.put("sch_code", school.getSchCode());
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233"); // 随机字符串
        jsonParam.put("bill_no",uuid);
        jsonParam.put("remark", preRegistration.getLevelName()+"-"+preRegistration.getMajorName());

        JSONObject stuMsg = new JSONObject();
        stuMsg.put("stu_name", preRegistration.getName());
        stuMsg.put("stu_idcard", preRegistration.getIdCard());
        stuMsg.put("stu_number", preRegistration.getId()+"");
        jsonParam.put("stu_info",stuMsg);

        // 收费项
        double moneyAll = 0;
        JSONArray chargeList = new JSONArray();
        for(ChargesItems chargesItems : chargesItemsList){
            moneyAll += chargesItems.getMoney();

            JSONObject chargeItems1 = new JSONObject();
            chargeItems1.put("item_code",chargesItems.getChargesCode());
            chargeItems1.put("item_amount",chargesItems.getMoney());
            chargeList.add(chargeItems1);
        }
        jsonParam.put("charge_items",chargeList); // 添加收费项
        jsonParam.put("total_amount",moneyAll); // 总金额

        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, school.getPrivateKey());
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData); //签名
        String url = baseURL+"edupay/api/pay/putbill";

        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        JSONObject resultObj = JSONObject.parseObject(resultStr);
        if(resultObj.getInteger("code") != 0){
            return R.error("推送缴费失败。状态码："+resultObj.getInteger("code"));
        }

        // 推送成功才有记录
        PreLog preLog = new PreLog();
        preLog.setCreateTime(new Date());
        preLog.setBillMoney(moneyAll);
        preLog.setStatus(resultObj.getInteger("code"));
        preLog.setStuName(preRegistration.getName());
        preLog.setBillNo(uuid);
        preLog.setSendJson(jsonStr);
        preLog.setSchoolId(school.getId());
        preLog.setRegistrationId(preRegistration.getId());
        preLog.setStuIdcard(preRegistration.getIdCard());
        preLogMapper.insert(preLog);
        preRegistration.setStatus(1); //推送成功
        preRegistrationMapper.updateStatus(preRegistration);
        return R.ok();

    }

    @Override
    public R reloadFeeStatus(String billNo) {

        PreLog preLog = preLogMapper.selectByBillId(billNo);
        if(preLog == null){
            return R.error("没找到该订单");
        }

        School school = schoolDao.queryObject(preLog.getSchoolId());
        if(school == null){
            return R.error("学校不清");
        }

        JSONObject longs = JSONObject.parseObject(preLog.getSendJson());
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", longs.getString("appid"));
        jsonParam.put("sch_code", longs.getString("sch_code"));
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233"); // 随机字符串
        jsonParam.put("bill_no",billNo);

        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, school.getPrivateKey());
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData);
        String url = baseURL+"edupay/api/pay/querypay";
        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        System.out.println(resultStr);

        // 获取是否已经交完费
        JSONObject jsonObject = JSONObject.parseObject(resultStr);
        if(jsonObject.getInteger("code") == 0){
            // 缴费金额：
            // 已缴费金金额
            double total_amount = jsonObject.getJSONObject("data").getDouble("total_amount");
            double paid_amount = jsonObject.getJSONObject("data").getDouble("paid_amount");
            if(total_amount == paid_amount){
                // 缴费交清了
                preLog.setStatus(1);
                preLogMapper.updateById(preLog);
            }
            return R.ok();
        }else{
            return R.ok(jsonObject.getString("msg"));
        }

    }

    @Override
    public R delFeeStatus(String billNo) {
        PreLog preLog = preLogMapper.selectByBillId(billNo);
        if(preLog == null){
            return R.error("没找到该订单");
        }

        School school = schoolDao.queryObject(preLog.getSchoolId());
        if(school == null){
            return R.error("学校不清");
        }

        // 先查询，看是否缴费成功
        try{
            reloadFeeStatus(billNo);
        }catch (Exception e){

        }
        preLog = preLogMapper.selectByBillId(billNo);
        if(preLog.getStatus() == 1){
            return R.error("该学生已经缴费，不能删除！");
        }

        // 已取消，直接删除
        if(preLog.getStatus() == 3){
            PreRegistration preRegistration = preRegistrationMapper.selectById(preLog.getRegistrationId());
            if(preRegistration == null){
                return R.error("系统异常");
            }
            preRegistration.setStatus(0);
            preRegistrationMapper.updateStatus(preRegistration);
            preLogMapper.deleteById(preLog.getId());
            return R.ok();
        }

        JSONObject longs = JSONObject.parseObject(preLog.getSendJson());
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", longs.getString("appid"));
        jsonParam.put("sch_code", longs.getString("sch_code"));
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233"); // 随机字符串
        jsonParam.put("bill_no",billNo);

        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, school.getPrivateKey());
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData);
        String url = baseURL+"edupay/api/pay/deletebill";
        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        System.out.println(resultStr);

        JSONObject resultObj = JSONObject.parseObject(resultStr);
        if(resultObj.getInteger("code") != 0){
            return R.error("删除缴费信息失败。状态码："+resultObj.getInteger("code"));
        }

        PreRegistration preRegistration = preRegistrationMapper.selectById(preLog.getRegistrationId());
        if(preRegistration == null){
            return R.error("系统异常");
        }
        preRegistration.setStatus(0);
        preRegistrationMapper.updateStatus(preRegistration);
        preLogMapper.deleteById(preLog.getId());
        return R.ok();

    }

    @Override
    public R cancelFree(String billNo) {
        PreLog preLog = preLogMapper.selectByBillId(billNo);
        if(preLog == null){
            return R.error("没找到该订单");
        }

        School school = schoolDao.queryObject(preLog.getSchoolId());
        if(school == null){
            return R.error("学校不清");
        }

        // 先查询，看是否缴费成功
        try{
            reloadFeeStatus(billNo);
        }catch (Exception e){

        }
        preLog = preLogMapper.selectByBillId(billNo);
        if(preLog.getStatus() == 1){
            return R.error("该学生已经缴费，不能删除！");
        }

        JSONObject longs = JSONObject.parseObject(preLog.getSendJson());
        JSONObject jsonParam = new JSONObject();
        jsonParam.put("appid", longs.getString("appid"));
        jsonParam.put("sch_code", longs.getString("sch_code"));
        jsonParam.put("nonce_str", "21df7dc9cd8616b56919f20d9f679233"); // 随机字符串
        jsonParam.put("bill_no",billNo);
        jsonParam.put("remark",billNo);

        // 将json对象转为ASCII码从小到大排序的字符串
        String jsonStr = JSONObject.toJSONString(jsonParam, SerializerFeature.MapSortField);
        // 获得签名
        String signData = SignUtil.sign(jsonStr, school.getPrivateKey());
        // 将签名内容封装进json对象
        jsonParam.put("sign", signData);
        String url = baseURL+"edupay/api/pay/deletebill";
        String resultStr = HttpRequest.sendJSONPost(jsonParam.toJSONString(),url);
        System.out.println(resultStr);

        JSONObject resultObj = JSONObject.parseObject(resultStr);
        if(resultObj.getInteger("code") != 0){
            return R.error("删除缴费信息失败。状态码："+resultObj.getInteger("code"));
        }

        PreLog cpreLog = new PreLog();
        cpreLog.setId(preLog.getId());
        cpreLog.setStatus(3);
        int row = preLogMapper.updateById(cpreLog);

        return R.resultRow(row);
    }

    @Override
    public List<PreRegistration> queryByIdcard(String idCard) {
        return preRegistrationMapper.queryByIdCard(idCard);
    }

    @Override
    public int changeMajor(PreRegistration registration) {
        return preRegistrationMapper.changeMajor(registration);
    }

    @Override
    public int changeMajorByLog(PreRegistration registration) {

        PreRegistration oldRegistration = preRegistrationMapper.selectById(registration.getId());
        if(oldRegistration == null){
            return 0;
        }
        LevelChangeLog levelChangeLog = new LevelChangeLog();
        levelChangeLog.setOld_pre(oldRegistration.toString());
        levelChangeLog.setNew_pre(registration.toString());
        levelChangeLog.setRegistration_id(registration.getId());
        levelChangeLog.setUser_id(ShiroUtils.getUserId());

        preRegistrationMapper.insertLevelLog(levelChangeLog);
        return preRegistrationMapper.updateById(registration);
    }

}
